import { Injectable } from '@angular/core';
import { Action, State, StateContext, Store } from '@ngxs/store';
import { SystemAction } from './system.action';
import { Clipboard } from '@angular/cdk/clipboard';
import { AuthService } from '../../shared/auth/auth.service';
import { mergeMap, tap } from 'rxjs';
import { AuthGuard } from '../../shared/auth/auth.guard';
import { ActivatedRoute, RouterStateSnapshot } from '@angular/router';
import { RouterSelector } from '../router/router.selector';
import { NzMessageService } from 'ng-zorro-antd/message';
import { Navigate } from '@ngxs/router-plugin';

export interface SystemStateModel {
  /**
   * 临时数据
   */
  tempData?: any;
  user?: any;
  token?: string;
  dictionary: any;
  userInfoForm: any;
  userLoginForm: any;
}

@State<SystemStateModel>({
  name: 'system',
  defaults: {
    dictionary: {},
    userInfoForm: {},
    userLoginForm: {},
  },
})
@Injectable({
  providedIn: 'root',
})
export class SystemState {

  constructor(
      private clipboard: Clipboard,
      private auth: AuthService,
      private store: Store,
      private authGuard: AuthGuard,
      private route: ActivatedRoute,
      private message: NzMessageService,
  ) {
  }

  @Action(SystemAction.SaveTempData)
  saveTempData(ctx: StateContext<SystemStateModel>, {data}: SystemAction.SaveTempData) {
    ctx.patchState({tempData: data});
  }

  @Action(SystemAction.Copy)
  copyText(ctx: StateContext<SystemStateModel>, data: SystemAction.Copy) {
    this.clipboard.copy(data.text);
  }

  @Action(SystemAction.SaveUser)
  SaveUser(ctx: StateContext<SystemStateModel>, {data}: SystemAction.SaveUser) {
    ctx.patchState({user: data});
  }

  @Action(SystemAction.SaveToken)
  SaveToken(ctx: StateContext<SystemStateModel>, {token}: SystemAction.SaveToken) {
    ctx.patchState({token});
  }

  @Action(SystemAction.InitialConfig)
  InitialConfig(ctx: StateContext<SystemStateModel>) {
    return this.auth.initialConfig().pipe(tap((r: any) => {
      ctx.patchState({user: r.user, dictionary: r.dictionary});
    }));
  }

  @Action(SystemAction.ModifyUserInfo)
  ModifyUserInfo(ctx: StateContext<SystemStateModel>) {
    const form = ctx.getState().userInfoForm;
    if (form.status === 'INVALID') {
      return;
    }
    return this.auth.modifyUserInfo(form.model).pipe(tap((r: any) => {
      ctx.patchState({user: r});
    }));
  }

  @Action(SystemAction.Login)
  Login(ctx: StateContext<SystemStateModel>) {
    let state = ctx.getState();
    let userLoginForm = state.userLoginForm;
    if (userLoginForm.invalid) {
      return;
    }
    const token = btoa(userLoginForm.model.username + ':' + userLoginForm.model.password);
    ctx.patchState({token});
    return this.auth.initialConfig()
        .pipe(tap({
          next: () => {
            this.message.success(`登录成功`);
          },
          error: () => {
            this.message.error(`登录失败`);
          },
        }))
        .pipe(mergeMap((r: any) => ctx.dispatch([new SystemAction.SaveUser(r.user), new SystemAction.SaveToken(token)])))
        .pipe(mergeMap(() => ctx.dispatch(new Navigate(['/']))));
  }

  @Action(SystemAction.Logout)
  Logout() {
    const url = this.store.selectSnapshot(RouterSelector.url);
    let currentRoute = this.route.root.children['0'];
    const routerStateSnapshot: RouterStateSnapshot = Object.assign({},
        currentRoute.snapshot, {url});
    this.authGuard.canActivate(currentRoute.snapshot, routerStateSnapshot);
  }
}
